package com.thinkcoer.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;

@Slf4j
@Aspect
@Component
@Order(1)
public class AuthAspect {

    @Pointcut(value = "execution(* com.*.controller.*.*(..))")
    public void authPointCut(){ }

    @Before(value = "authPointCut()")
    public void doBefore(JoinPoint point){
        log.info("【用户认证切面:Before方法执行了】");
    }

    @Around(value = "authPointCut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("【用户认证切面:执行目标方法前Around方法执行】");
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String serverName = request.getServerName();
        String queryString = request.getQueryString();
        //拿到HttpServletRequest对象就可以对权限进行校验
        //如果校验不通过，直接 return null即可，就不会请求到控制器方法
        Object proceed = joinPoint.proceed();
        log.info("【用户认证切面:执行目标方法后Around方法执行】");
        return proceed;
    }

    @After(value = "authPointCut()")
    public void doAfter(){
        log.info("【用户认证切面:After方法执行】");
    }

    @AfterReturning(returning = "ret",value = "authPointCut()")
    public void doAfterReturn(JoinPoint joinPoint,Object ret){
        log.info("【用户认证切面:AfterReturning方法执行】");
    }

    @AfterThrowing(value = "authPointCut()",throwing ="throwable")
    public void doAfterThrowing(Throwable throwable){
        log.info("【用户认证切面:AfterThrowing方法执行】");
    }
}
